package com.xhh.nphm.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.xhh.nphm.common.core.domain.Ztree;

import com.xhh.nphm.common.core.domain.entity.Dept;
import com.xhh.nphm.system.domain.*;

import com.xhh.nphm.system.mapper.*;
import com.xhh.nphm.system.service.ICommonService;
import com.xhh.nphm.system.service.IDeptDeadLineService;
import com.xhh.nphm.system.service.ISortService;

import com.xhh.nphm.web.controller.system.BaiduApiController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class CommonServiceImpl implements ICommonService {
    @Autowired
    private CommonDao commonDao;
    @Autowired
    private WorkFormBaseDao workFormBaseDao;
    @Autowired
    private IDeptDeadLineService deptDeadLineService;
    @Autowired
    private MmailWorkFormDao mmailWorkFormDao;
    @Autowired
    private BaiduApiController baiduApiController;
    @Autowired
    private SysUserLoginSateDao sysUserLoginSateDao;

    private static Cache<String, List<Map>> build = Caffeine.newBuilder()
            // .initialCapacity(10) 初始大小
            // .maximumSize(10)  最大数量
            // .expireAfterWrite(4, TimeUnit.DAYS) 过期时间
            .build();

    @Autowired
    private ISortService sortService;

    @Autowired
    private TelGetDealDao telGetDealDao;

    /**
     * 清除缓存
     */
    public static void clearCatch() {
        build.invalidateAll();
    }

    /**
     * 查询内容分类
     * easyui combobox
     * @return
     */
    @Override
    public List<Map> findContentCate() {
        build.get("findContentCate", s -> {
            List<NodeCate> list = commonDao.findContentCate();
            NodeCate item = new NodeCate();
            item.setId("11");
            List<NodeCate> nodeCateList = children3(item, list);
            List listMap = new ArrayList();
            Map<String, Object> map = new HashMap<>();
            map.put("contentCate", nodeCateList);
            listMap.add(map);
            return listMap;
        });
        return build.getIfPresent("findContentCate");
    }

    @Override
    public List<Map> findWork(String content,String areaName) {
        String body = "{" +
                "    \"title\": \"\"," +
                "    \"content\": \""+ content+"\"," +
                "    \"dial_area\": \""+areaName+"\"" +
                "}";
        return baiduApiController.assigner(body);
    }

    /**
     * 查询地区
     *
     * @return
     */
    @Override
    public List<Map> findArea() {
        build.get("area", s -> commonDao.findArea());
        return build.getIfPresent("area");
    }

    /**
     * 查询用户类别
     *
     * @return
     */
    @Override
    public List<Map> findUserType() {
        build.get("userType", s -> commonDao.findUserType());
        return build.getIfPresent("userType");
    }

    /**
     * 查询坐席备注
     *
     * @return
     */
    @Override
    public List<Map> findSeatsRemark() {
        build.get("seatsRemark", s -> commonDao.findSeatsRemark());
        return build.getIfPresent("seatsRemark");
    }


    /**
     * 查询交办意见，坐席处理
     *
     * @return
     */
    @Override
    public List<Map> findOpinion() {
        build.get("opinion", s -> commonDao.findOpinion());
        return build.getIfPresent("opinion");
    }

    /**
     * 查询信件处理意见
     *
     * @return
     */
    @Override
    public List<Map> findOpinionM() {
        build.get("opinionM", s -> commonDao.findOpinionM());
        return build.getIfPresent("opinionM");
    }

    /**
     * 查询证件类型
     *
     * @return
     */
    @Override
    public List<Map> findCerType() {
        build.get("cerType", s -> commonDao.findCerType());
        return build.getIfPresent("cerType");
    }

    /**
     * 查询敏感信息属性种类
     *
     * @return
     */
    @Override
    public List<SensitiveInfoField> findSensitiveField() {
        return commonDao.findSensitiveField();
    }


    /**
     * 查询来电类别
     *
     * @return
     */
    @Override
    public List<Map> findTelType() {
        build.get("telType", s -> commonDao.findTelType());
        return build.getIfPresent("telType");
    }

    /**
     * 查询工单性质
     *
     * @return
     */
    @Override
    public List<Map> findWorkFormType() {
        build.get("workFormType", s -> commonDao.findWorkFormType());
        return build.getIfPresent("workFormType");
    }

    /**
     * 查询办理方式
     *
     * @return
     */
    @Override
    public List<Map> findBanliType() {
        build.get("banliType", s -> commonDao.findDealWay());
        return build.getIfPresent("banliType");
    }

    /**
     * 查询内容分类
     *
     * @return
     */
    @Override
    public List<Map> findContentCategories() {
        build.get("contentCategoriesTree", s -> commonDao.findContentCategories());
        return build.getIfPresent("contentCategoriesTree");
    }

    /**
     * 查询系统公告类别
     *
     * @return
     */
    @Override
    public List<Map> findNtcTypes() {
        build.get("ntcTypes", s -> commonDao.findNtcTypes());
        List<Map> ntcTypes = build.getIfPresent("ntcTypes");
        //剔除专向
        ntcTypes = ntcTypes.stream().filter(f->!f.get("CSValue").equals("31")).collect(Collectors.toList());
        return ntcTypes;
    }

    /**
     * 办理期限 不能做缓存，每个工单的办理期限不一样
     *
     * @param date yyyy-MM-dd
     * @return
     */
    @Override
    public String nextXWorkdayGet(String date) {
        return commonDao.nextXWorkdayGet(date);
    }

    /**
     * 办理期限
     *
     * @param day  延期天数
     * @param date yyyy-MM-dd
     * @return
     */
    @Override
    public String nextXWorkdayGet(int day, String date) {
        return commonDao.myNextXWorkdayGet(day,date);
    }

    /**
     * 上级催办键
     * @param deptId
     * @return
     */
    @Override
    public Map<String, Object> supUrgeOrder(String deptId) {
        Map<String, Object> map = new HashMap<>();
        map.put("tel",commonDao.supUrgeTelOrder(deptId));
        map.put("mail",commonDao.supUrgeMailOrder(deptId));
        return map;
    }

    /**
     * 查询延期理由
     *
     * @return
     */
    @Override
    public List<Map> delayReasonList() {
        build.get("delayReason", s -> commonDao.delayReasonList());
        return build.getIfPresent("delayReason");
    }

    public List<Ztree> selectSortList() {
        QueryWrapper<BSort> wrapper = new QueryWrapper<>();
        List<BSort> list = sortService.list(wrapper);
        List<Ztree> ztrees = initZtree1(list);
        return ztrees;
    }

    public List<Ztree> initZtree(List<BSort> sorts) {
        return initZtree1(sorts);
    }

    public List<Ztree> initZtree1(List<BSort> deptList) {
        List<Ztree> ztrees = new ArrayList<Ztree>();
        for (BSort sort : deptList) {
            Ztree ztree = new Ztree();
            if (sort.getCodepk() != "" && sort.getCodepk() != null && sort.getCodepk().length() > 0) {
                ztree.setId(Long.parseLong(sort.getCodepk()));
            }
            ztree.setpId(Long.parseLong(sort.getCodeparent()));
            ztree.setName(sort.getSortname());
            ztree.setTitle(sort.getSortname());
            ztrees.add(ztree);
        }
        return ztrees;
    }

    public List<Ztree> selectSortTreeExcludeChild(BSort sort) {
        String codepk = sort.getCodepk();
        QueryWrapper<BSort> wrapper = new QueryWrapper<>();
        List<BSort> list = sortService.list(wrapper);
        Iterator<BSort> it = list.iterator();
        while (it.hasNext()) {
            BSort d = (BSort) it.next();
            if (Long.parseLong(d.getCodepk()) == Long.parseLong(codepk)) {
                it.remove();
            }
        }
        List<Ztree> ztrees = initZtree(list);
        return ztrees;
    }

    public String makeRandomStr(int fpLength) {
        String rtnStr = "";
        String chars = "0123456789";
        char[] rands = new char[fpLength];
        for (int i = 0; i < fpLength; i++) {
            int rand = (int) (Math.random() * 10.0D);
            rands[i] = chars.charAt(rand);
            rtnStr = new StringBuilder().append(rtnStr).append(rands[i]).toString();
        }
        return rtnStr;
    }

    public String byTelGetSN(int fpLen) {
        String rtn = "1";
        String tmpNO = "";
        String tmpStr = "";
        String cYear = "";
        String cMth = "";
        String cDay = "";
        String rYear = "";
        String rMth = "";
        String rDay = "";
        int tmpInt = -1;
        Calendar myDay = Calendar.getInstance();

        tmpInt = myDay.get(1);
        cYear = String.valueOf(tmpInt);
        tmpInt -= 2000;
        rYear = String.valueOf(tmpInt);

        tmpInt = myDay.get(2) + 1;
        cMth = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rMth = "0" + cMth;
        else {
            rMth = cMth;
        }
        tmpInt = myDay.get(5);
        cDay = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rDay = "0" + cDay;
        else {
            rDay = cDay;
        }
        tmpInt = this.countSNbyDate(cYear, cMth, cDay);
        tmpInt++;
        tmpNO = Integer.toString(tmpInt);
        if (tmpNO.length() >= fpLen) {
            tmpStr = tmpNO;
        } else {
            String zeroPre = "";
            for (int i = 0; i < fpLen - tmpNO.length(); i++) {
                zeroPre = zeroPre + "0";
            }
            tmpStr = zeroPre + tmpNO;
        }

        rtn = rtn + rYear + rMth + rDay + tmpStr;
        return rtn;
    }

    public int countSNbyDate(String fpYear, String fpMth, String fpDay) {
        int rtnNum = -1;
        String hql = telGetDealDao.selectByDate(fpYear, fpMth, fpDay);
        rtnNum = Integer.parseInt(hql);
        return rtnNum;
    }

    private List<NodeCate> children3(NodeCate item, List<NodeCate> list) {
        List<NodeCate> nodeCateList = list.stream().filter(temp -> temp.getPid().equals(item.getId())).collect(Collectors.toList());
        for (NodeCate nodeCate : nodeCateList) {
            List<NodeCate> dataList = list.stream().filter(temp -> temp.getPid().equals(nodeCate.getId())).collect(Collectors.toList());
            nodeCate.setChildren(dataList);
            for (NodeCate nodeCate2 : dataList) {
                nodeCate2.setChildren(children3(nodeCate2, list));
            }
        }
        return nodeCateList;
    }


    public String byMWFGetNO(int fpLen)
    {
        String rtn = "";
        String tmpNO = ""; String tmpStr = "";
        String cYear = ""; String cMth = ""; String cDay = "";
        String rYear = ""; String rMth = ""; String rDay = "";
        int tmpInt = -1;
        Calendar myDay = Calendar.getInstance();

        tmpInt = myDay.get(1);
        cYear = String.valueOf(tmpInt);
        tmpInt -= 2000;
        rYear = String.valueOf(tmpInt);

        tmpInt = myDay.get(2) + 1;
        cMth = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rMth = "0" + cMth;
        else {
            rMth = cMth;
        }
        tmpInt = myDay.get(5);
        cDay = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rDay = "0" + cDay;
        else {
            rDay = cDay;
        }
        tmpInt = countNObyDate(cYear, cMth, cDay);
        tmpInt++;
        tmpNO = Integer.toString(tmpInt);
        if (tmpNO.length() >= fpLen) {
            tmpStr = tmpNO;
        }
        else {
            String zeroPre = "";
            for (int i = 0; i < fpLen - tmpNO.length(); i++) {
                zeroPre = zeroPre + "0";
            }
            tmpStr = zeroPre + tmpNO;
        }

        rtn = rtn + rYear + rMth + rDay + "M" + tmpStr;
        return rtn;
    }

    public int countNObyDate(String fpYear, String fpMth, String fpDay) {
        int rtnNum = -1;
        String hql = mmailWorkFormDao.selectByDate(fpYear, fpMth, fpDay);
        rtnNum = Integer.parseInt(hql);
        return rtnNum;
    }

    /**
     * 工单编号自动生成
     *
     * @param fpLen
     * @return
     */
    public String byWFGetNO(int fpLen) {
        String rtn = "";
        String tmpNO = "";
        String tmpStr = "";
        String cYear = "";
        String cMth = "";
        String cDay = "";
        String rYear = "";
        String rMth = "";
        String rDay = "";
        int tmpInt = -1;
        Calendar myDay = Calendar.getInstance();

        tmpInt = myDay.get(1);
        cYear = String.valueOf(tmpInt);
        tmpInt -= 2000;
        rYear = String.valueOf(tmpInt);

        tmpInt = myDay.get(2) + 1;
        cMth = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rMth = "0" + cMth;
        else {
            rMth = cMth;
        }
        tmpInt = myDay.get(5);
        cDay = String.valueOf(tmpInt);
        if (tmpInt < 10)
            rDay = "0" + cDay;
        else {
            rDay = cDay;
        }
        tmpInt = this.countSNbyDate1(cYear, cMth, cDay);
        tmpInt++;
        tmpNO = Integer.toString(tmpInt);
        if (tmpNO.length() >= fpLen) {
            tmpStr = tmpNO;
        } else {
            String zeroPre = "";
            for (int i = 0; i < fpLen - tmpNO.length(); i++) {
                zeroPre = zeroPre + "0";
            }
            tmpStr = zeroPre + tmpNO;
        }

        rtn = rtn + rYear + rMth + rDay + "T" + tmpStr;
        return rtn;
    }

    public int countSNbyDate1(String fpYear, String fpMth, String fpDay) {
        int rtnNum = -1;
        String hql = workFormBaseDao.selectByDate(fpYear, fpMth, fpDay);
        rtnNum = Integer.parseInt(hql);
        return rtnNum;
    }

    /**
     * 查询本级部门
     *
     * @param fpArea
     * @param deptNo
     * @return
     */
    public List<Map> queryFlatDept(String fpArea, String deptNo) {
//        build.get("queryFlatDept", s -> commonDao.queryFlatDept(fpArea, deptNo));
//        return build.getIfPresent("queryFlatDept");
        //锦江区市场监管局 锦江区住建局 春熙路街道办事处 东湖街道办事处
        Dept dept = commonDao.findDeptById(deptNo);
        if(dept != null && dept.getLayerNum() != null ) {
//        if("359040".equals(deptNo) || "329040".equals(deptNo) || "301040007".equals(deptNo) || "301040034".equals(deptNo)) {
            if(dept.getLayerNum() == 3) return commonDao.queryFlatDeptFourthZhiNeng(deptNo);
            else if(dept.getLayerNum() == 4) return null;
        }
        else if(deptNo.length() >= 12) {
            return null;
        }
        return commonDao.queryFlatDept(fpArea,deptNo);
    }

    /**
     * 查询下级部门
     * 区(市)县
     *
     * @param fpParent
     * @return
     */
    public List<Map> querySonDept(String fpParent) {
        if (fpParent.length()>3&&fpParent.startsWith("304")){
            fpParent = "301"+fpParent.substring(3,6);
        }
//        build.get("querySonDept", s -> commonDao.querySonDept(fpParent));
//        return build.getIfPresent("querySonDept");
        //锦江区市场监管局 锦江区住建局 春熙路街道办事处 东湖街道办事处
        Dept dept = commonDao.findDeptById(fpParent);
        if(dept != null && dept.getLayerNum() != null) {
//        if("359040".equals(fpParent) || "329040".equals(fpParent) || "301040007".equals(fpParent) || "301040034".equals(fpParent)) {
            if(dept.getLayerNum() == 3) return commonDao.querySonDeptFourthXiaQu(fpParent);
            else if(dept.getLayerNum() == 4) {
                //科室和社区（5级）被挂到3级父类
                List<Map> mapList = commonDao.querySonDeptCommunity(dept.getNoParent());
                if(mapList == null || mapList.size() == 0) {
                    // 5级挂到4级父类
                    mapList = commonDao.queryFlatDeptFifth(dept.getNoUnit());
                }
                return mapList;
            }
        }
        return commonDao.querySonDept(fpParent);
    }

    /**
     * @Description: 所有的部门
     * @Param: []
     * @return: List<Map>
     */
    public List<Map> allDepartment( String deptNo){
        return commonDao.findAllDept(deptNo);
    }

    @Override
    public List<String> findAllDept(String fpArea, String deptNo) {
        List<String> allDept = commonDao.findFlatDept(fpArea, deptNo);
        if (deptNo.length()>3&&deptNo.startsWith("304")){
            deptNo = "301"+deptNo.substring(3,6);
        }
        allDept.addAll(commonDao.findSonDept(deptNo));
        return allDept;
    }


    /**
     * 拟办期限自动生成
     *
     * @param
     * @return
     */
    public String getNxetBackLimit(int days){
        Calendar now = Calendar.getInstance();
        int year = now.get(Calendar.YEAR);
        int month = now.get(Calendar.MONTH) + 1;
        int day = now.get(Calendar.DAY_OF_MONTH);
        Map<String, Object> delayTime = commonDao.getNextXWorkday(year, month, day, days);
        String date = (String) delayTime.get("RtnStr");
        //去掉末尾小数点
        date = date.replace(".000", "");
        return date;
    }

    /**
     * 拟办期限自动生成
     *
     * @param
     * @return
     */
    public String getDeptBackLimit(String deptNo, int days){
        String result = null;
        DeptDeadLine deptDeadLine = deptDeadLineService.findBydeptNo(deptNo);
        if(deptDeadLine != null && deptDeadLine.getDelayDays() != null) {
            days = deptDeadLine.getDelayDays();
        }
        return getNxetBackLimit(days);
    }


    /**
     * 查询承办单位 对应编号
     * @param sbdeptName
     * @return
     */
    public String selectDeptShort(String sbdeptName) {
        return commonDao.selectDeptShort(sbdeptName);
    }

    /**
     * 查询重要代办事项
     *
     * @param fpRole 用户角色
     * @param unitId 部门编号
     * @return 列表
     */
    @Override
    public List<Map> psPgFstWait(String fpRole, String unitId, boolean flag) {
        Map<String,String> params = new HashMap<>(2);
        params.put("roleId",fpRole);
        params.put("deptId",unitId);
        if (flag){
            return commonDao.psPgFstWait_gxq(params);
        } else {
            return commonDao.psPgFstWait(params);
        }
    }

    public List<Map> loginState(Long deptParentId) {
        String s = deptParentId.toString();
        //查询下级部门 304040 → 301040
        if (s.length()>3&&s.startsWith("304")){
            s = "301"+s.substring(3,6);
        }
        return sysUserLoginSateDao.loginState(s);
    }

    public int areaAllCount(Long deptParentId) {
        return sysUserLoginSateDao.areaAllCount(deptParentId);
    }

    public int areaOnlineCount(Long deptParentId) {
        return sysUserLoginSateDao.areaOnlineCount(deptParentId);
    }

    @Override
    public List<String> findAllDeptId(String fpArea, String deptNo) {
        List<String> allDept = commonDao.findFlatDeptId(fpArea, deptNo);
        if (deptNo.length()>3&&deptNo.startsWith("304")){
            deptNo = "301"+deptNo.substring(3,6);
        }
        allDept.addAll(commonDao.findSonDeptId(deptNo));
        return allDept;
    }

    @Override
    public List<BSort> findBSortNoByName(String sortName, int level) {
        return commonDao.findBSortNoByName(sortName,level);
    }

    @Override
    public BSort selectBSortNoByParent(String sortName, String parentNo) {
        return commonDao.selectBSortNoByParent(sortName,parentNo);
    }

    @Override
    public List<Map> queryDirectDept(String fpParent) {
        if (fpParent.length()>3&&fpParent.startsWith("304")){
            fpParent = "301"+fpParent.substring(3,6);
        }
        return commonDao.queryDirectDept(fpParent);
    }
}
